﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.Xml;
using Microsoft.Extensions.FileProviders;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;

namespace StarUtils.Extension
{
    public static class ConfigUtils
    {
        private static readonly Dictionary<string, IConfigurationRoot> configDic = new Dictionary<string, IConfigurationRoot>();

        public static IConfigurationRoot GetJsonConfig(string configFileName = "appsettings.json", string basePath = "")
        {
            basePath = (basePath.IsNullOrWhiteSpace() ? Directory.GetCurrentDirectory() : Path.Combine(Directory.GetCurrentDirectory(), basePath));
            if (configDic.Keys.Any((string p) => p == configFileName + basePath))
            {
                return configDic.First((KeyValuePair<string, IConfigurationRoot> p) => p.Key == configFileName + basePath).Value;
            }

            if (!File.Exists(Path.Combine(basePath, configFileName)))
            {
                return null;
            }

            IConfigurationRoot configurationRoot = new ConfigurationBuilder().SetBasePath(basePath).AddJsonFile(configFileName, optional: true, reloadOnChange: true).Build();
            if (!configDic.Any((KeyValuePair<string, IConfigurationRoot> p) => p.Key == configFileName + basePath))
            {
                configDic.Add(configFileName + basePath, configurationRoot);
            }

            return configurationRoot;
        }

        public static IConfigurationRoot GetXmlConfig(string configFileName, string basePath = "")
        {
            basePath = (basePath.IsNullOrWhiteSpace() ? Directory.GetCurrentDirectory() : Path.Combine(Directory.GetCurrentDirectory(), basePath));
            return new ConfigurationBuilder().AddXmlFile(delegate (XmlConfigurationSource config)
            {
                config.Path = configFileName;
                config.FileProvider = new PhysicalFileProvider(basePath);
                config.ReloadOnChange = false;
            }).Build();
        }

        public static IConfigurationRoot GetConfigRoot(string fileName)
        {
            string text = Path.Combine(Directory.GetCurrentDirectory(), "Config", fileName);
            bool flag = File.Exists(text);
            int num = 0;
            while (!flag)
            {
                Thread.Sleep(1000);
                num++;
                flag = File.Exists(text);
                if (num > 10)
                {
                    throw new Exception(fileName + "文件未能被创建...." + text);
                }
            }

            return GetJsonConfig(fileName, Path.Combine(Directory.GetCurrentDirectory(), "Config"));
        }
    }


    public static class DbConnetStringFrom
    {
        private static readonly IConfigurationRoot _nosqlConfigRoot = ConfigUtils.GetConfigRoot("NoSql.json");

        public static string GetEFConnectString(string name)
        {
            string empty = string.Empty;
            empty = GetConnectStringByConfigRoot(ConfigUtils.GetConfigRoot("ConnectionStrings.json"), name);
            if (empty.IsNullOrWhiteSpace())
            {
                empty = GetConnectStringByConfigRoot(ConfigUtils.GetConfigRoot(Path.Combine("private", "ConnectionStrings.json")), name);
            }

            return empty;
        }

        public static string GetRedisConfig(string key)
        {
            IConfigurationSection configurationSection = _nosqlConfigRoot?.GetSection("NoSql:Redis");
            if (configurationSection != null)
            {
                return configurationSection[key];
            }

            return string.Empty;
        }

        public static string GetRedisConfigInArray(string key, string keyName, string valueName, string keyValue)
        {
            IConfigurationRoot nosqlConfigRoot = _nosqlConfigRoot;
            if (nosqlConfigRoot != null)
            {
                IEnumerable<IConfigurationSection> enumerable = nosqlConfigRoot.GetSection("NoSql:Redis:" + key)?.GetChildren();
                if (enumerable != null)
                {
                    foreach (IConfigurationSection item in enumerable)
                    {
                        string key2 = item.Path + ":" + keyName;
                        if (nosqlConfigRoot[key2] == keyValue)
                        {
                            return nosqlConfigRoot[item.Path + ":" + valueName];
                        }
                    }
                }
            }

            return string.Empty;
        }

        public static Dictionary<string, string> GetRedisKeyDic(string configName)
        {
            IEnumerable<IConfigurationSection> enumerable = _nosqlConfigRoot.GetSection("NoSql:Redis:Biz:" + configName + ":Keys:Key")?.GetChildren();
            Dictionary<string, string> dictionary = new Dictionary<string, string>();
            if (enumerable != null)
            {
                foreach (IConfigurationSection item in enumerable)
                {
                    dictionary.Add(_nosqlConfigRoot[item.Path + ":name"], _nosqlConfigRoot[item.Path + ":#text"]);
                }

                return dictionary;
            }

            return dictionary;
        }

        public static string GetMongoDbConfig(string key)
        {
            IConfigurationSection configurationSection = _nosqlConfigRoot?.GetSection("NoSql:MongoDB");
            if (configurationSection != null)
            {
                return configurationSection[key];
            }

            return string.Empty;
        }

        private static string GetConnectStringByConfigRoot(IConfigurationRoot configurationRoot, string connectionName)
        {
            IEnumerable<IConfigurationSection> enumerable = configurationRoot?.GetSection("ConnectionStrings:Add")?.GetChildren();
            if (enumerable != null)
            {
                foreach (IConfigurationSection item in enumerable)
                {
                    string key = item.Path + ":name";
                    if (configurationRoot[key] == connectionName)
                    {
                        return configurationRoot[item.Path + ":connectionString"];
                    }
                }
            }

            return string.Empty;
        }
    }
}
